package com.om.exposed;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

/**
 * Run this with the following JVM arguments to invoke contest:
 * -javaagent:../commonlibs/ConTest.jar
 * -Dcontest.preferences=../commonlibs/KingProperties
 */

public class ValueWithObjectTest {
	private static final int THREADS = 2;
	private static final int LOOPS = 15;
	ObjectWithValue object;

	@Before
	public void init() {
		object = new ObjectWithValue();
	}

	Runnable incrementValue = new Runnable() {
		public void run() {
			for (int i = 0; i < LOOPS; ++i)
				object.incrementValue();
		}
	};

	@Test
	public void singleThreaded() throws InterruptedException {
		Thread t = new Thread(incrementValue);
		t.start();
		t.join();
		assertEquals(LOOPS, object.getValue());
	}

	@Test
	public void demonstrateMultipleThreadsFail() throws InterruptedException {
		Thread[] threads = new Thread[THREADS];

		for (int i = 0; i < threads.length; ++i)
			threads[i] = new Thread(incrementValue);

		for (Thread t : threads)
			t.start();
		for (Thread t : threads)
			t.join();

		int expected = LOOPS * THREADS;
		String message = String.format("Correct value: %d, actual value: %d",
				expected, object.getValue());
		assertTrue(message, expected != object.getValue());
		System.out.println(message);
	}
}
